import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.util.ArrayList;
import javax.swing.border.Border;
/** Componente per visualizzare tabelle con numeri viariabili di righe per ogni colonne
 *  Nel caso specifico delle differenze finite, le colonne, procedendo dalla prima all'ultima,
 *  hanno sempre una riga in meno della precedente.
 *
 *  Ogni cella di JTabella e' un JTextBox, e' possibile prelevare o impostare i valori di queste celle
 *  tramite un arrayList di arrayList di Double. (vedi funzioni setData, getData)
 *
 *  JTabella contiene due JPanel come figli diretti, uno tiene delle JLabel con l'intestazione delle colonne
 *  e uno tiene un insieme di JPanel ognuno per ogni colonna inserita che a sua volta contiene un insieme
 *  di JTextBox ognuno per ogni cella della tabella.
 *  
 * -JTabella
 *     -JPanel 
 *        -JLabel "x"
 *        -JLabel "f(x)"
 *     -JPanel
 *        -JPanel
 *          -Insieme di JTextBox con le ascisse
 *        -JPanel
 *          -Insieme di JTextBox con le ordinate
 *        -Altri JPanel ognuno dei quali contiene 
 *          -altre JTextBox per le varie colonne delle differenze fintie
 */

public class JTabella extends JPanel  {

    int righe; //numero massimo di righe della tabella
    //(coincide col numero di ascisse, overo il nuero di punti da interpolare)

    static final int width=100; //lunghezza cella in pixel
    static final int height=24;  //altezza cella in pixel

    JPanel tabella; //pannello su cui disegnare le JTextField

    //come parametro passo il numero massimo di righe, serve a disegnare la tabella.
    public JTabella (int n)  {
        super();
        righe = n;
        initComponents();
    }

    public void initComponents()
    {
        //richiedo una dimensione un po piu grande dello stretto necessario
        //perche' oltre alle celle JTextField ci sono anche delle JLabel come intestazione
        this.setPreferredSize(new Dimension((10+width)*(righe+1),height*(righe+2)));

        {
            //aggiungo un pannello con le intestazioni
            JPanel jp = new JPanel();
            jp.setLayout(new BoxLayout(jp,BoxLayout.X_AXIS));
            jp.setPreferredSize(new Dimension((10+width)*(righe+1),height));

            JLabel x = new JLabel("x");
            x.setHorizontalAlignment(JLabel.CENTER);
            x.setPreferredSize(new Dimension(width+30,height));

            JLabel fx = new JLabel("f(x)");
            fx.setHorizontalAlignment(JLabel.CENTER);
            fx.setPreferredSize(new Dimension(width,height));

            JPanel gap = new JPanel();
            gap.setPreferredSize(new Dimension(10,height));

            jp.add(x);
            jp.add(fx);
            jp.add(gap);

            this.add(jp);
        }

        tabella = new JPanel();
        tabella.setPreferredSize(new Dimension((10+width)*(righe+1),height*(righe+1)));

        //Creo la tabella triangolare, questa e' la prima colonna di "righe" colonne 
        //dove verranno visualizzate le ascisse

        {
            JPanel jp = new JPanel();
            jp.setBorder(null);

            for(int j=0;j<righe;j++){
                JTextField jtf = new JTextField();
                jtf.setPreferredSize(new Dimension(width,height-6));
                jp.add(jtf);
            }
            jp.setPreferredSize(new Dimension(width,height*righe));
            jp.setVisible(true);
            tabella.add(jp);
        }
        //Creo la tabella triangolare, questa e' la prima colonna di "righe" colonne 
        //dove verranno visualizzate le ordinate e a seguire tutte le diffenze, con un numero di righe
        //pari a "righe-i",dove i e' l'indice della colonna.

        for(int i=0;i<righe;i++)
        {
            JPanel jp = new JPanel();
            for(int j=0;j<righe-i;j++)
            {
                JTextField jtf = new JTextField();
                jtf.setPreferredSize(new Dimension(width,height-6));
                // System.err.println("un pannello carico carico carico di "+(righe-i));
                jp.add(jtf);
            }
            jp.setVisible(true);
            jp.setPreferredSize(new Dimension(width,height*(righe-i)));
            tabella.add( jp);
            //         jp.setBounds(i*100,20*i,100,20*(righe-i));
        }
        this.add(tabella);

        setVisible(true);
    }

    //restituisce i dati presenti in un arraylist di arraylist di double
    public ArrayList <ArrayList <Double>> getData()
    {
        ArrayList <ArrayList <Double>> al = new ArrayList <ArrayList <Double>>();
        int n =tabella.getComponentCount();
        for(int i=0;i<n;i++)
        {
            ArrayList <Double> a = new ArrayList <Double> ();
            JPanel panel = (JPanel)tabella.getComponent(i);
            for(int j=0;j<panel.getComponentCount();j++)
            {

                double v = get(i,j);
                a.add(v);
            }
            al.add(a);
        }
        return al;
    }

    //carica un array di array di double dentro ai JTextBox
    public void setData(ArrayList <ArrayList <Double>> al)
    {

        for(int i=0;i<al.size();i++)
        {
            ArrayList <Double> a = al.get(i);
            for(int j=0;j<a.size();j++)
            {

                set(i,j,a.get(j));
//                System.out.print(" "+a.get(j)+ " ");
            }

        }

    }

    //imposta il valore di una singola JTextBox
    //come parametro viene fornito il numero di colonna e di riga
    //il primo rappresenta l'indice JPanel a cui accedere
    //il secondo l'indice della JTextBox a cui accedere dentro a quel JPanel
    public void set(int n,int m,double v)
    {
        JPanel jp=(JPanel)tabella.getComponent(n);
        JTextField jtf = (JTextField)jp.getComponent(m);
        jtf.setText(Double.toString(v));
    }

    //preleva il valore di una singola jtextbox 
    //(do per scontate che l'utente inserisca numeri double)!
    //come parametro viene fornito il numero di colonna e di riga
    //il primo rappresenta l'indice JPanel a cui accedere
    //il secondo l'indice della JTextBox a cui accedere dentro a quel JPanel
    public double get(int n,int m)
    {
        JPanel jp=(JPanel)tabella.getComponent(n);
        JTextField jtf = (JTextField)jp.getComponent(m);
        try
        {
            return Double.parseDouble(jtf.getText());
        }catch(NumberFormatException ex)
        {
            return 0; //se il numero non e' doublizzabile restituisco zero
        }
    }

}
